/*
 * WorkLayer.cpp
 *
 *  Created on: 2010-9-6
 *      Author: try
 */

#include "WorkPage.h"
#include "WorkLayer.h"
#include "StatusLayer.h"
#include "shape/AbstractShape.h"
#include "shape/Shape.h"
#include "shape/Ellipse.h"
#include "shape/Rectangle.h"
#include "shape/Merger.h"
#include "shape/ControlPoint.h"

using namespace Thk;

namespace S {
    WorkLayer::WorkLayer(WorkPage* page): Layer(page),
      selectModeCursor(NULL),drawModeCursor(NULL), isDrawingFlag(false)
      , transformControlPoint(NULL)
      {

      selectModeCursor = new DefaultCursor(LoadCursor(NULL,IDC_ARROW));
      drawModeCursor = new DefaultCursor(LoadCursor(NULL,IDC_CROSS));
    }

    WorkLayer::~WorkLayer(){
      std::vector<Shape*> tmpShapes;
      tmpShapes.insert(tmpShapes.end(), allShapes.begin(), allShapes.end());
      ShapeIterator it = tmpShapes.begin();
      for(; it != tmpShapes.end(); it++){
        deleteShape(*it);
      }

      if(selectModeCursor)delete selectModeCursor;
      if(drawModeCursor)delete drawModeCursor;
    }

    void WorkLayer::switchCursor(){
      WorkPage* page = (WorkPage*)drawPage;
      switch(page->getWorkMode()){
        case WorkPage::SelectMode:
          setCursor(selectModeCursor);
          break;
        default:
          setCursor(drawModeCursor);
      }
    }

    void WorkLayer::drawEllipse(real ex, real ey){
      real w = 1;//66;
      real h = 1;//66;
      drawShape(new Ellipse(ex-w, ey-h, w, h));
    }

    void WorkLayer::drawRectangle(real ex, real ey){
      real w = 1;
      real h = 1;
      drawShape(new Rectangle(ex-w, ey-h, w, h));
    }

    void WorkLayer::drawShape(Shape* s, bool drawing){
      addElement(s, getShapeNums());
      allShapes.push_back(s);
      s->createPath();
      getSelection()->clear();
      s->setSelected(true);
      setDrawing(drawing);
      WorkPage* page = (WorkPage*)getDrawPage();
      page->getStatusLayer()->showElementNums(getShapeNums());
    }

    /**
     * 将选中元素移动到顶层
     */
    void WorkLayer::adjustToTop(){
      Selection* selection = getSelection();
      if(selection->empty()){
        return;
      }
      vector<Element*> seledEls;
      sortElements(&seledEls, selection->getElements());

      vector<Element*>::iterator it = seledEls.begin();
      for(; it != seledEls.end(); it++){
        Shape* s = (Shape*)*it;
        addElement(s, getShapeNums());
        //s->adjustControlPointPosition();
      }
      selection->redrawAll();
    }

    /**
     * 将选中元素移动到底层
     */
    void WorkLayer::adjustToBottom(){
      Selection* selection = getSelection();
      if(selection->empty()){
        return;
      }
      vector<Element*> seledEls;
      sortElements(&seledEls, selection->getElements());

      vector<Element*>::reverse_iterator it = seledEls.rbegin();
      for(; it != seledEls.rend(); it++){
        Shape* s = (Shape*)*it;
        addElement(s, 0);
      }
      selection->redrawAll();
    }

    /**
     * 将选中元素下移一层
     */
    void WorkLayer::adjustToNext(){
      Selection* selection = getSelection();
      if(selection->empty()){
        return;
      }
      vector<Element*> seledEls;
      sortElements(&seledEls, selection->getElements());

      if(seledEls[0]==getElements()->at(0)){
        return;
      }
      vector<Element*>::const_iterator it = seledEls.begin();
      for(; it != seledEls.end(); it++){
        Shape* s = (Shape*)*it;
        adjustElement(s, -1, s);
      }
      selection->redrawAll();
    }

    /**
     * 将选中元素上移一层
     */
    void WorkLayer::adjustToUp(){
      Selection* selection = getSelection();
      if(selection->empty()){
        return;
      }
      vector<Element*> seledEls;
      sortElements(&seledEls, selection->getElements());
      if(seledEls[seledEls.size()-1]==getElements()->at(getShapeNums()-1)){
        return;
      }
      vector<Element*>::reverse_iterator begin = seledEls.rbegin();
      vector<Element*>::reverse_iterator it = begin;
      for(; it != seledEls.rend(); it++){
        Shape* s = (Shape*)*it;
        adjustElement(s, 2, s);
      }
      selection->redrawAll();
    }


    /**
     * 合并选中图形
     */
    void WorkLayer::merge(){
//      cout<<"WorkLayer.merge, this is "<<this<<endl;
      Selection* selection = getSelection();
      const vector<Element*>* seledEls =  selection->getElements();
      if(seledEls->size()<2){
        return;
      }
      //创建组合器
      Merger* merger = new Merger();
      merger->addShapes(selection->getAbstractElements());

      //从层中移除被选中的元素
      vector<Element*>::const_iterator it = seledEls->begin();
      for(; it != seledEls->end(); it++){
        ((Shape*)(*it))->setMerged(true);
        removeElement(*it);
        ShapeIterator sit = std::find(allShapes.begin(), allShapes.end(), *it);
        if(sit != allShapes.end()){
          allShapes.erase(sit);
        }
      }
      drawShape(merger, false);
    }

    /**
     * 取消组合
     */
    void WorkLayer::unmerge(){
      Selection* selection = getSelection();
      if(selection->empty()){
        return;
      }
      vector<AbstractElement*> seledEls;
      selection->removes(&seledEls);

      vector<AbstractElement*>::const_iterator it = seledEls.begin();
      for(; it != seledEls.end(); it++){
        Shape* s = (Shape*)*it;
        if(s->isMerger()){
          Merger* m = (Merger*)s;
          const std::vector<Shape*>* els = m->getShapes();
          if(!els->empty()){
            vector<Shape*>::const_iterator it = els->begin();
            for(; it != els->end(); it++){
              (*it)->setMerged(false);
            }
            m->redrawIntersection();
            addElements((const std::vector<AbstractElement*>*)els, getShapeNums());
            allShapes.insert(allShapes.end(), els->begin(), els->end());
            selection->addAll((const std::vector<AbstractElement*>*)els);
            m->clear();
            deleteShape(m);
          }else{
            selection->add(s);
          }
        }
      }
    }


    /**
     * 删除图形
     */
    void WorkLayer::deleteShape(Shape* s){
      removeElement(s);
      ShapeIterator sit = std::find(allShapes.begin(), allShapes.end(), s);
      if(sit != allShapes.end()){
        allShapes.erase(sit);
      }

      if(s->isMerger()){
        const vector<Shape*>* els = ((Merger*)s)->getShapes();
        vector<Shape*>::const_iterator it = els->begin();
        for(; it != els->end(); it++){
          deleteShape((Shape*)(*it));
        }
      }
      delete s;
      WorkPage* page = (WorkPage*)getDrawPage();
      page->getStatusLayer()->showElementNums(getShapeNums());
    }


    bool WorkLayer::event(const Event* e){
      return Layer::event(e);
    }


    void WorkLayer::mousePressEvent(const MouseEvent* e){
//      cout<<"WorkLayer.mousePressEvent, this is "<<this<<endl;
      real ex = e->x();
      real ey = e->y();
      WorkPage* page = (WorkPage*)drawPage;
      AbstractShape* hoveringElement = (AbstractShape*)getMouseHoveringElement();
//      cout<<"WorkLayer.mousePressEvent, hoveringElement is "<<hoveringElement<<endl;
      bool mouseInHovering = hoveringElement && hoveringElement->intersects(ex, ey);
//      cout<<"WorkLayer.mousePressEvent, mouseInHovering is "<<mouseInHovering<<endl;
      bool isControlPoint = mouseInHovering && hoveringElement->isInstanceOf(ControlPoint::ClassId);
//      cout<<"WorkLayer.mousePressEvent, isControlPoint is "<<isControlPoint<<endl;
      if(e->pressed(MButton_Left)){
        //绘制图形
        switch(page->getWorkMode()){
          case WorkPage::DrawEllipseMode:
            drawEllipse(ex, ey);
            break;
          case WorkPage::DrawRectangleMode:
            drawRectangle(ex, ey);
            break;
          default:
            break;
        }

        const KeySequence& kseq = e->getKeySequence();
        //取消选择, 如果当前鼠标没有在活动元素上，就取消选择
        if(!kseq.test(Key_Shift)
            && !isDrawing()
            && (!mouseInHovering || !getSelection()->contains(hoveringElement))
            && !isControlPoint
            ){
            getSelection()->clear(); //清除选择的元素
        }

        //准备移动
         getSelection()->prepareTransform(ex, ey);

        //准备调整大小
        if(isControlPoint){
          prepareTransform(ex, ey);
          transformControlPoint = (ControlPoint*)hoveringElement;
        }
      }else
        //从绘图模式转换到选择模式
        if(e->pressed(MButton_Right)
          && page->getWorkMode()!=WorkPage::SelectMode
          ){
          page->setWorkMode(WorkPage::SelectMode);
      }
    }

    /**
     * 当鼠标在层上移动时
     */
    void WorkLayer::mouseMoveEvent(const MouseEvent* e) {
      //cout<<"WorkLayer.mouseMoveEvent.e.x() is "<<e->x()<<endl;
      //cout<<"WorkLayer.mouseMoveEvent.e.y() is "<<e->y()<<endl;
      WorkPage* page = (WorkPage*)drawPage;
      real ex = e->x();
      real ey = e->y();

      //继续画
      if(isDrawing()){
        Selection* selection = getSelection();
        real dx = ex-selection->referencePointX();
        real dy = ey-selection->referencePointY();
        Shape* s = (Shape*)(selection->getElements()->at(0));
        s->adjustSize(dx, dy, 4);
        selection->prepareTransform(ex, ey);
      }


      //移动选中图形
      const KeySequence& ks = e->getKeySequence();
      if(!ks.test(Key_Shift)
          && !transformControlPoint
          && page->getWorkMode() == WorkPage::SelectMode
          && e->pressed(MButton_Left)
          && getSelection()->isPreparingTransform()
          ){
        //移动所有选中元素
        getSelection()->moveTo(ex, ey);
      }

      //调整图形大小
      if(e->pressed(MButton_Left)
          && transformControlPoint && isPreparingTransform()){
        Shape* shape = transformControlPoint->getShape();
        real dx = ex-referencePointX();
        real dy = ey-referencePointY();
        shape->adjustSize(dx, dy, transformControlPoint->getIndex());
        prepareTransform(ex, ey);
      }

      //显示坐标
      page->getStatusLayer()->showCoordinate(ex, ey);

    }

    void WorkLayer::mouseReleaseEvent(const MouseEvent* e){
      getSelection()->endTransform();//结束移动
      endTransform();//结束调整大小
      transformControlPoint = NULL;
//      cout<<"WorkLayer.mouseReleaseEvent, this is 1 "<<this<<endl;
      if(isDrawing()){
        setDrawing(false);
        Selection* selection = getSelection();
//        cout<<"WorkLayer.mouseReleaseEvent, this is 2 "<<selection->size()<<endl;
        if(selection->size()>0){
          Shape* s = (Shape*)(selection->getElements()->at(0));
          if(std::abs((long)s->width()) <4 && std::abs((long)s->height()) <4 ){
            s->adjustSize(66, 66, 4);
          }
        }
      }
    }

    /**
     * 当鼠标从层上移出时
     */
    void WorkLayer::mouseLeaveEvent(const MouseEvent* e) {
//      cout<<"WorkLayer.mouseLeaveEvent, this is "<<this<<endl;
    }


    void WorkLayer::mouseDoubleClickEvent(const MouseEvent* e){
//      cout<<"WorkLayer.mouseDoubleClickEvent, this is "<<this<<endl;
    }

    void WorkLayer::mouseWheelEvent(const WheelEvent* e){
//      cout<<"WorkLayer.mouseWheelEvent, this is "<<this<<endl;
//      cout<<"WorkLayer.mouseWheelEvent, e.x() is "<<e->x()<<endl;
//      cout<<"WorkLayer.mouseWheelEvent, e.y() is "<<e->y()<<endl;
//      cout<<"WorkLayer.mouseWheelEvent, getDelta() is "<<e->getDelta()<<endl;
//      cout<<"WorkLayer.mouseWheelEvent, getOrientation() is "<<e->getOrientation()<<endl;
//      cout<<"WorkLayer.mouseWheelEvent, getButtons() is "<<e->getButtons()<<endl;
    }

    /**
     * 键被按下
     */
    void WorkLayer::keyPressEvent(const KeyEvent* e){
      //cout<<"WorkLayer.keyPressEvent, key is "<<e->getKey()<<endl;
      //删除选中元素
      if(e->test(Key_Delete)){
        Selection* selection = getSelection();
        vector<AbstractElement*> seledEls;
        selection->removes(&seledEls);
        if(seledEls.empty()){
          return;
        }
        vector<AbstractElement*>::iterator it = seledEls.begin();
        for(; it != seledEls.end(); it++){
          (*it)->redrawIntersection();
          deleteShape((Shape*)*it);
        }
        WorkPage* page = (WorkPage*)getDrawPage();
        page->getStatusLayer()->showElementNums(getShapeNums());
      }
    }

    /**
     * 键被释放
     */
    void WorkLayer::keyReleaseEvent(const KeyEvent* e){
//      cout<<"WorkLayer.keyReleaseEvent, key is "<<e->getKey()<<endl;
    }

    void WorkLayer::paintEvent(const PaintEvent* e){
      cout<<"WorkLayer.paintEvent "<<this<<endl;
      StatusLayer* statusLayer = ((WorkPage*)getDrawPage())->getStatusLayer();
      statusLayer->showDrawedCount(getDrawElementCount());
      statusLayer->showRefreshSpendTime(getDrawSpendTime());
    }

}

